<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>正则基础介绍</title>
</head>
<body>
<script>
    /*
     "^" ：^会匹配行或者字符串的起始位置，有时还会匹配整个文档的起始位置。
     "$"  ：$会匹配行或字符串的结尾
     "\b"(boundary) :不会消耗任何字符只匹配一个位置，常用于匹配单词边界;
        如:我想从字符串中"This is Regex"匹配单独的单词"is"正则就要写成"\bis\b";\b:不会匹配is两边的字符，但它会识别is两边是否为单词的边界
     "\d"(digit): 匹配数字:
        例如要匹配一个固定格式的电话号码以0开头前4位后7位，如0737-5686123  正则:^0\d\d\d-\d\d\d\d\d\d\d$
     "\w"(word)：匹配字母，数字，下划线:
        例如我要匹配"a2345BCD__TTz" 正则："\w+"  这里的"+"字符为一个量词指重复的次数。
     "\s"(space)：匹配空格:
        例如字符 "a b c" =>正则："\w\s\w\s\w":一个字符后跟一个空格，如有字符间有多个空格直接把"\s" 写成 "\s+" 让空格重复
     "."：匹配除了换行符以外的任何字符;这个算是"\w"的加强版,"\w"不能匹配空格;如果把字符串加上空格用"\w"就受限了
        看下用 "."是如何匹配字符"a23 4 5 B C D__TTz"  正则：".+"
     "[abc]": 字符组  匹配包含括号内元素的字符;这个比较简单了只匹配括号内存在的字符，还可以写成[a-z]匹配a至z的所以字母就等于可以用来控制只能输入英文了
     ***************************
     反义
     "\W"   匹配任意不是字母，数字，下划线 的字符
     "\S"   匹配任意不是空白符的字符
     "\D"  匹配任意非数字的字符
     "\B"  匹配不是单词开头或结束的位置
     "[^abc]"  匹配除了abc以外的任意字符
     **************************************
     量词:
     先解释关于量词所涉及到的重要的三个概念:
     1:贪婪(贪心) 如"*"字符 贪婪量词会首先匹配整个字符串，尝试匹配时，它会选定尽可能多的内容，如果失败则回退一个字符，然后再次尝试回退的过程就叫做回溯，它会每次回退一个字符，直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的，
     2:懒惰(勉强) 如 "?"  懒惰量词使用另一种方式匹配，它从目标的起始位置开始尝试匹配，每次检查一个字符，并寻找它要匹配的内容，如此循环直到字符结尾处。
     3:占有:如"+" 占有量词会覆盖事个目标字符串，然后尝试寻找匹配内容 ，但它只尝试一次，不会回溯，就好比先抓一把石头，然后从石头中挑出黄金
     "*"(贪婪)   重复零次或更多:例如"aaaaaaaa" 匹配字符串中所有的a  正则： "a*"   会出到所有的字符"a"
     "+"(懒惰)   重复一次或更多次:例如"aaaaaaaa" 匹配字符串中所有的a  正则： "a+"  会取到字符中所有的a字符，  "a+"与"a*"不同在于"+"至少是一次而"*" 可以是0次，稍后会与"?"字符结合来体现这种区别
     "?"(占有)   重复零次或一次
        例如"aaaaaaaa" 匹配字符串中的a 正则 ： "a?" 只会匹配一次，也就是结果只是单个字符a
     "{n}"  重复n次
        例如从"aaaaaaaa" 匹配字符串的a 并重复3次 正则：  "a{3}"  结果就是取到3个a字符  "aaa";
     "{n,m}"  重复n到m次
        例如正则 "a{3,4}" 将a重复匹配3次或者4次 所以供匹配的字符可以是三个"aaa"也可以是四个"aaaa" 正则都可以匹配到
     "{n,}"  重复n次或更多次
        与{n,m}不同之处就在于匹配的次数将没有上限，但至少要重复n次;如:正则"a{3,}"a至少要重复3次把量词了解了之后之前匹配电话号码的正则现在就可以改得简单点了^0\d\d\d-\d\d\d\d\d\d\d可以改为"0\d+−\d7"。这样写还不够完美如果因为前面的区号没有做限定，以至于可以输入很多，而通常只能是3位或者4位，现在再改一下"^0\d{2,3}-\d{7}"如此一来区号部分就可以匹配3位或者4位的了
     ***********************************************
     懒惰限定符
     　　"*?"    重复任意次，但尽可能少重复;如 "acbacb"  正则  "a.*?b" 只会取到第一个"acb" 原本可以全部取到但加了限定符后，只会匹配尽可能少的字符 ，而"acbacb"最少字符的结果就是"acb"
     "+?"    重复1次或更多次，但尽可能少重复;与上面一样，只是至少要重复1次
     "??"  重复0次或1次，但尽可能少重复;如:"aaacb" 正则 "a.??b" 只会取到最后的三个字符"acb"
     "{n,m}?"  重复n到m次，但尽可能少重复;如:"aaaaaaaa"  正则 "a{0,m}" 因为最少是0次所以取到结果为空
     "{n,}?"    重复n次以上，但尽可能少重复;如:"aaaaaaa"  正则 "a{1,}" 最少是1次所以取到结果为 "a"
     ***********************************************
     三  正则进阶
     捕获分组:先了解在正则中捕获分组的概念，其实就是一个括号内的内容;如 "(\d)\d" 而"(\d)"这就是一个捕获分组，可以对捕获分组进行;后向引用(如果后而有相同的内容则可以直接引用前面定义的捕获组，以简化表达式);如(\d)\d\1 这里的"\1"就是对"(\d)"的后向引用
     那捕获分组有什么用呢看个例子就知道了:如  "zery zery";正则:\b(\w+)\b\s\1\b 所以这里的"\1"所捕获到的字符也是 与(\w+)一样的"zery"，为了让组名更有意义，组名是可以自定义名字的:"\b(?<name>\w+)\b\s\k<name>\b" 用"?<name>"就可以自定义组名了而要后向引用组时要记得写成 "\k<name>";自定义组名后,捕获组中匹配到的值就会保存在定义的组名里;
     下面列出捕获分组常有的用法
     "(exp)"(expression)    匹配exp,并捕获文本到自动命名的组里
     "(?<name>exp)"   匹配exp,并捕获文本到名称为name的组里
     "(?:exp)"  匹配exp,不捕获匹配的文本，也不给此分组分配组号
     以下为零宽断言:
     "(?=exp)"  匹配exp前面的位置:如 "How are you doing" 正则"(?<txt>.+(?=ing))" 这里取ing前所有的字符，并定义了一个捕获分组名字为 "txt" 而"txt"这个组里的值为"How are you do";
     "(?<=exp)"  匹配exp后面的位置:如 "How are you doing" 正则"(?<txt>(?<=How).+)" 这里取"How"之后所有的字符，并定义了一个捕获分组名字为 "txt" 而"txt"这个组里的值为" are you doing";
     "(?!exp)":匹配后面跟的不是exp的位置:如 "123abc" 正则 "\d{3}(?!\d)"匹配3位数字后非数字的结果
     "(?<!exp)":匹配前面不是exp的位置:如 "abc123" 正则 "(?<![0-9])123":匹配"123"前面是非数字的结果也可写成"(?!<\d)123";
    * */
</script>
<div>

</div>
<script>
    var reg = /^\s*<(\w+|!)[^>]*>/;
    // var reg = /^\s*<(\w+|!)[^>]*>/
    var str = '  <div>111</div>'
    console.log(str.match(reg,str))
</script>
</body>
</html>